

package hmm;

/**
 * Implementation of a Markov model, that will be used by the hmm.
 * NOTE: The implementation of the Markov model assumes the following:
 * 		Possible observations are numbers from 0 to (M-1).
 * 		States are numbered from 0 to (N-1).
 */
public class MarkovModel {
	
	/**
	 * The constructor initiates the Markov model
	 * NOTE: the implementation of the Markov model assumes the following:
	 * 		States are numbered from 0 to (N-1).
	 * @param N Number of states in the model
	 * @param M Number of observation symbols
	 * @param pr MarkovianProbabilities implementation, a class that implements
	 * 			probability tables (see the interface's comments).
	 * @param pi A vector of size N, gives each state the probability to
	 * 			start at this state the Markov process.
	 * @param T The length of the observation vector.
	 * @throws HmmException in case of wrong input
	 */
	public MarkovModel(int N, int M, MarkovianProbabilities pr,
			double[] pi, int T) throws HmmException {
		checkInput(N, M, pr, pi, T);
		this.N = N;
		this.M = M;
		this.pr = pr;
		this.pi = pi;
		this.T = T;
	}
	
	/**
	 * @return the length of the observation sequence
	 */
	public int getT() {
		return T;
	}
	/**
	 * @return the number of states in the model
	 */
	public int getN() {
		return N;
	}
	/**
	 * @return the number of observations in the model
	 */
	public int getM() {
		return M;
	}
	/**
	 * @return the Markovian probabilities class
	 */
	public MarkovianProbabilities getPr() {
		return pr;
	}
	/**
	 * @return the initial states probabilities
	 */
	public double[] getPi() {
		return pi;
	}
	
	/*
	 * check that the input parameters are legal.
	 * NOTE: don't check pr! just verify it's not null!
	 */
	private void checkInput(int N, int M, MarkovianProbabilities pr, double[] pi, int T) throws HmmException {
		if(N <= 0) { throw new HmmException("MarkovModel", "N is illigal"); }
		if(M <= 0) { throw new HmmException("MarkovModel", "M is illigal"); }
		if(pr == null) {
			throw new HmmException("MarkovModel", "pr can't be null");
		}
		if(pi.length != N) {
			throw new HmmException("MarkovModel", "The size of pi is illigal");
		}
		for(int i = 0; i < pi.length; i++) {
			if(pi[i] < 0 || pi[i] > 1) {
				throw new HmmException("MarkovModel", "pi["+i+"] is illigal");
			}
		}
		if(T < 0) {
			throw new HmmException("MarkovModel", "The length of the observation vector should be integer bigger than 0");
		}
	}
	
	private int N; // Number of states in the model
	private int M; // Number of observation symbols
	private MarkovianProbabilities pr; // MarkovianProbabilities implementation,
		// a class that implements probability tables (see the interface's comments).
	private double[] pi; // A vector of size N, gives each state the 
		// probability to start at this state the Markov process.
	private int T;
}
